package com.central.scheduler.plugin.task.api;

import com.central.scheduler.plugin.task.util.OSUtils;
import com.central.scheduler.spi.task.TaskConstants;
import com.central.scheduler.spi.task.request.TaskRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author Tindy
 * @date 2021/11/15
 * @describe
 */
public final class ProcessUtils {
    private static final Logger logger = LoggerFactory.getLogger(ProcessUtils.class);

    private ProcessUtils() {
        throw new IllegalStateException("Utility class");
    }

    /**
     * Initialization regularization, solve the problem of pre-compilation performance,
     * avoid the thread safety problem of multi-thread operation
     */
    private static final Pattern MACPATTERN = Pattern.compile("-[+|-]-\\s(\\d+)");

    /**
     * Expression of PID recognition in Windows scene
     */
    private static final Pattern WINDOWSATTERN = Pattern.compile("(\\d+)");

    /**
     * kill tasks according to different task types.
     */
    public static void kill(TaskRequest request) {
        try {
            int processId = request.getProcessId();
            if (processId == 0) {
                logger.error("process kill failed, process id :{}, task id:{}",
                        processId, request.getTaskInstanceId());
                return;
            }

            String cmd = String.format("kill -9 %s", getPidsStr(processId));
//            cmd = OSUtils.getSudoCmd(request.getTenantCode(), cmd);
            logger.info("process id:{}, cmd:{}", processId, cmd);

            OSUtils.exeCmd(cmd);
        } catch (Exception e) {
            logger.error("kill task failed", e);
        }
    }

    /**
     * get pids str.
     *
     * @param processId process id
     * @return pids pid String
     * @throws Exception exception
     */
    public static String getPidsStr(long processId) throws Exception {
        StringBuilder sb = new StringBuilder();
        Matcher mat = null;
        // pstree pid get sub pids
        if (OSUtils.isMacOS()) {
            String pids = OSUtils.exeCmd(String.format("%s -sp %d", TaskConstants.PSTREE, processId));
            if (null != pids) {
                mat = MACPATTERN.matcher(pids);
            }
        } else {
            String pids = OSUtils.exeCmd(String.format("%s -p %d", TaskConstants.PSTREE, processId));
            mat = WINDOWSATTERN.matcher(pids);
        }

        if (null != mat) {
            while (mat.find()) {
                sb.append(mat.group(1)).append(" ");
            }
        }

        return sb.toString().trim();
    }

}

